Cartesi Rollups 之 交易管理器
在 Cartesi,我们每天都会遇到与缺乏成熟工具相关的问题。 区块链是一项新兴技术,软件堆栈仍处于起步阶段,并且发展速度很快。 针对这些问题编写临时解决方案是不可扩展的。 更好的方法是以可重用的方式在已建立的较低级别解决方案之上构建抽象。
必须指出的是,这些较低级别的解决方案是开源的,由社区开发。同样,我们也从中受益,我们正在发布自己的内部工具,这可能会使社区受益。
之前,我们谈到了通过 State Fold 读取智能合约的状态,这是与区块链交互的第一步。事务管理器是下一步。该工具解决了将交易发送到区块链的问题。在很多方面,它是 State Fold 的对偶:State Fold 读取账本的状态,而交易管理器写入账本的状态。
背景Background
交易推动区块链状态向前发展。它们是区块链之外的用户对分布式账本进行状态更改的方式。常见的交易类型包括将 Ether 转移到其他地址、调用智能合约的方法(例如 ERC20 代币转移)和实例化智能合约。在 Cartesi Rollups的背景下,交易的示例包括向Rollups添加输入、进行状态哈希声明以及与防欺诈纠纷进行交互。
交易由用户帐户发送,也称为外部所有者帐户。交易首先由用户使用帐户的私钥签名,然后广播到网络以包含在未来区块的分布式账本中。它们包含诸如“to”地址(可以是另一个用户帐户或智能合约)、有效载荷(包含我们想要发送到智能合约的数据)、gas 价格以及我们想要在 Ethers 中转移的价值等信息。
从矿工的角度来看,交易首先被添加到所谓的交易池中。交易池是每个以太坊节点的本地结构。它保存了矿工在创建新区块时提取的一组交易。将它们视为要包含在区块链中的交易队列。然而,由于这个队列是每个节点的本地队列,它的排序由每个单独的矿工决定。
一般来说,矿工首先选择产生最高利润的交易:交易添加到区块链的顺序与它们添加到池中的顺序不对应。将交易添加到区块链的盈利能力的合理启发是交易的gas价格。因此,通常首先将具有较高 gas 价格的交易添加到分布式账本中。
从用户帐户发送到区块链的交易必须按升序进行唯一编号,没有间隙。此编号称为随机数,是交易的一部分。具有重复随机数的交易是互斥的。如果交易池包含两笔具有相同随机数的交易,矿工只能将其中的一笔加入区块链(一般是gas价格较高的那笔)。
在实践中,当我们想要发送交易时,我们通过以太坊的 JSON-RPC API 来完成,该 API 通常封装在一些高级库中,例如 web3.js。这个库与一个远程提供者通信,我们必须在使用它之前指定它。对这个提供商的信任是必不可少的:恶意提供商可以简单地忽略我们的请求并拒绝广播我们的交易。但是,它不能伪造或修改我们的交易:加密签名可以确保这一点。
由于提供商必须与以太坊网络通信,因此它必须运行一个以太坊节点。通常有两种设置方法。第一个是自己做。我们选择以太坊协议的一个实现,例如 Geth 或 Parity,并在某些机器上运行它。这个设置并不简单。第二种方法是将其委托给某些外部提供商,例如 Infura 或 Alchemy。
发送交易Sending transactions
确保将交易添加到区块链说起来容易做起来难。管理交易存在多个陷阱和障碍,如果我们希望创建一个健壮的应用程序,就必须解决这些问题。
第一步是构建交易数据本身,然后对其进行签名并将其发送到以太坊节点。部分交易数据是固定的,从某种意义上说,我们不能在不改变交易效果的情况下随意更改它。其中的例子是“to”地址、有效载荷和以太值。它们是交易固有的,是“应用程序逻辑”的一部分,与“提交交易逻辑”分开。
交易数据的一些参数是外在的,因为它们(通常)不会改变交易的影响。这些例子是随机数和gas价格。它们不是应用程序逻辑的一部分,从某种意义上说,纯粹是官僚主义的。
然而,必须谨慎选择它们以确保我们的交易被添加到区块链中:错误的随机数将导致交易永远不会被添加,并且指定一个低的 gas 价格会阻塞用户帐户。即便如此,gas价格也不是一成不变的,会受到剧烈波动的影响。如果 gas 价格飙升,以看似合理的 gas 价格提交交易可能仍然会阻塞用户帐户,指定太高的 gas 价格又会浪费金钱。
以稳健的方式发现正确的随机数并不像看起来的那么简单。获取随机数的规范方法是计算该用户帐户添加到区块链的交易数量。如果用户不经常发送交易,在发送下一个交易之前总是等待前一个交易被挖掘,这很有效。否则,我们可能会遇到重复的随机数:交易池可能包含更多未被计算在内的交易。
更糟糕的是,交易可能会被任意从交易池中删除。除了可能错过重要的反应之外,被丢弃的交易可能会毒害用户帐户:如果随机数编号存在间隙,则在填补间隙之前,帐户将无法进一步的交易。
很明显,我们不能仅仅提交交易并期望将其添加到分布式账本中。如果我们想编写一个健壮的应用程序,应用程序和提供者之间必须有一些簿记逻辑。这种簿记逻辑还必须对进程重新启动具有弹性:我们必须能够以全新的方式打开我们的应用程序并使其正常运行。
交易管理器
Transaction Manager
交易管理器是将交易稳健地提交到区块链的解决方案。它可用作 Rust 库,并处理所有这些簿记逻辑。
要通过管理器提交交易,我们必须首先指定内在的交易数据和提交策略。该策略用于确定gas价格。管理器将持续监控区块链和gas价格,并将按照提交策略重新提交价格过时的交易。
如果一笔交易从交易池中被删除,它会被管理器自动重新提交。随机数也是自动管理的。当交易第一次提交时,管理器会为交易分配正确的随机数,在重新提交交易时重用随机数。如果交易提交的策略比以前的交易更高,则管理器会将旧交易提升到更新的策略。这样做是为了确保旧的定价过低的交易不会阻塞用户帐户。所有这些都是并发处理的,不会阻塞主应用程序。
我们的管理器也可以尝试取消已发送的交易。取消交易不是保证的事情。一旦提交到区块链,交易就无法撤销。但是,当它们仍在交易池中时,我们可能会尝试覆盖它们。诀窍包括提交一个什么都不做的新交易(比如向自己转移零以太),但与我们希望取消的交易具有相同的随机数,并且具有更高的gas价格。这样,矿工就有可能将具有较高 gas 价格的交易而不是原始交易打包在内,从而有效地取消原始交易。用户仍然需要支付交易的基本费用。
我们正在发布交易管理器的第一个版本。管道中有多项改进,我们渴望在他们准备好时与社区分享,包括与 EIP-1559 相关的调整。
Cartesi正在将智能合约推向新的高度。它是一个与链无关的第二层基础架构,解决了区块链上最紧迫的可扩展性问题。最值得注意的是,Cartesi实现了独特的支持Linux的VM,rollups和侧链,以彻底改变开发人员创建区块链应用程序的方式,允许他们使用主流软件组件。